package demo1;

/**
 * @author 余鹏龙
 * @version 1.0
 */

class OutClass2 {

    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;

    //静态内部类  定义在一个类的里面
    static class InnerClass2 {
        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;

        public void func2() {
            System.out.println("static->InnerClass::func()");
            //问题2  这里我们看到data1和data2不能被直接访问到
            //为什么？
            //我们可以想到静态方法是不依赖于对象的
            //当时data1和data2是属于对象的，这就说明静态内部类中没有这俩个外部类的对象
            //那我们只能通过类名来引用这两个对象了

            //总结  静态内部类中 不能直接访问外部类中的非静态成员
            OutClass2 outClass2 = new OutClass2();
            System.out.println(outClass2.data1);
            System.out.println(outClass2.data2);
//            System.out.println(data1);  error
//            System.out.println(data2);  error
            System.out.println(data3);
            System.out.println(this.data4);  //可以加一个this  代表静态内部类中当前对象的引用
            System.out.println(data5);
            System.out.println(data6);
        }
    }

    //对于OutClass这个类既可以有成员，也可以有成员方法
    public void test() {
        InnerClass2 innerClass2 = new InnerClass2();  //通过外部类对象内部对象的引用，可以访问data4和data5
        //问题就在data5中，之前博哥讲过私有的只能在类内部使用
        //这里大家要注意一下
        //以后说内部类要带前缀，什么内部类？  ->   外部类可以访问静态内部类当中所有成员，哪怕你是私有private，也可以访问（语法）
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);
        //data4，data5，data6不能直接访问
        //那我们该如何去访问？
        //System.out.println(data4);
        System.out.println(innerClass2.data4);
        //System.out.println(data5);  //data5是私有的
        System.out.println(innerClass2.data5);
        //System.out.println(data6);  //data6是静态的，通过类名进行访问
        System.out.println(InnerClass2.data6);

    }
}

// 内部类  在数据结构的时候会使用到
// 内部类也可以理解为 -> 构成外部类的最小单元
// 单链表 二叉树 以及其他数据结构会涉及到相关知识点
// 一种语法，一种选择
class OutClass {

    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;

    //静态内部类  定义在一个类的里面
    static class InnerClass {
        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;

        public void func() {
            System.out.println("static->InnerClass::func()");
            //问题2  这里我们看到data1和data2不能被直接访问到
            //为什么？
            //我们可以想到静态方法是不依赖于对象的
            //当时data1和data2是属于对象的，这就说明静态内部类中没有这俩个外部类的对象
            //那我们只能通过类名来引用这两个对象了

            //总结  静态内部类中 不能直接访问外部类中的非静态成员
            OutClass outClass = new OutClass();
            System.out.println(outClass.data1);
            System.out.println(outClass.data2);
//            System.out.println(data1);  error
//            System.out.println(data2);  error
            System.out.println(data3);
            System.out.println(this.data4);  //可以加一个this  代表静态内部类中当前对象的引用
            System.out.println(data5);
            System.out.println(data6);
        }
    }

    //对于OutClass这个类既可以有成员，也可以有成员方法
    public void test() {
        InnerClass innerClass = new InnerClass();  //通过外部类对象内部对象的引用，可以访问data4和data5
        //问题就在data5中，之前博哥讲过私有的只能在类内部使用
        //这里大家要注意一下
        //以后说内部类要带前缀，什么内部类？  ->   外部类可以访问静态内部类当中所有成员，哪怕你是私有private，也可以访问（语法）
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);
        //data4，data5，data6不能直接访问
        //那我们该如何去访问？
        //System.out.println(data4);
        System.out.println(innerClass.data4);
        //System.out.println(data5);  //data5是私有的
        System.out.println(innerClass.data5);
        //System.out.println(data6);  //data6是静态的，通过类名进行访问
        System.out.println(InnerClass.data6);

    }
}

//接口
interface IA {
    public static final int a = 100;
    public void func();
}
//实现接口，并重写接口方法
class AA implements IA {
    @Override
    public void func() {
        System.out.println("hello!!!");
    }
}

public class Test {
    public static void main(String[] args) {
        //匿名内部类,加个花括号，重写接口方法
        //等价于一个类实现了接口，并重写了接口中的方法，但这个类没有名字
        new IA() {
            @Override
            public void func() {
                System.out.println("我去！");
            }
        }.func();  //调用匿名内部类的方法也很简单，直接在花括号的后面.方法
        //后面写的时候会经常使用到匿名内部类，包括lambda表达式和匿名内部类之间也存在着一定的关联
        //甚至一个普通的类也可以使用到匿名内部类
    }
    public static void main4(String[] args) {
        IA ia = new AA();
        ia.func();
    }
    public static void main3(String[] args) {
        //既然内部类是一个类，那么一定可以实例化出一个静态内部类对象
        //如何实例化静态内部类对象？
        //InnerClass innerClass = new InnerClass();  //error  所以静态内部类不能在这里直接进行一个实例化
        //那它该如何去写呐
        //静态方法调用方式  类名.静态方法  内部类也类似  类名.内部类
        OutClass.InnerClass innerClass = new OutClass.InnerClass();  //看起来有点奇怪，一个有趣的知识点
        innerClass.func();
        //匿名内部类
        //与实现接口，重写接口方法效果等同

    }
}
